package main

import (
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"strings"
)

type ExportQueryFieldMap struct {
	Title     string
	Key       string
	Format    string
	Processor func(v string) string
}

func (p *ExportQueryFieldMap) toStr(data map[string]interface{}) string {
	if data == nil {
		return ""
	}

	v, ok := data[p.Key]
	if !ok {
		return ""
	}

	var res string

	if p.Format == "" {
		res = fmt.Sprint(v)
	} else {
		res = fmt.Sprintf(p.Format, v)
	}

	if p.Processor != nil {
		res = p.Processor(res)
	}

	if res != "" && res[0] == '0' {
		res = "\t" + res
	}

	return res
}

type ExportQuery struct {
	FieldMaps []ExportQueryFieldMap
}

func (p *ExportQuery) AppendFieldMap(fms ...ExportQueryFieldMap) {
	p.FieldMaps = append(p.FieldMaps, fms...)
}

func (p *ExportQuery) FieldTitles() string {
	var res = ""

	for _, v := range p.FieldMaps {
		res += v.Title + ","
	}

	return res
}

func (p *ExportQuery) ToStrings(datas interface{}) []string {
	buf, _ := json.Marshal(datas)
	var newDatas []map[string]interface{}
	json.Unmarshal(buf, &newDatas)

	if len(p.FieldMaps) == 0 || len(newDatas) == 0 {
		return make([]string, 0)
	}

	res := make([]string, len(newDatas)+1)

	var sLine string

	res[0] = p.FieldTitles()

	for k, v := range newDatas {
		sLine = ""
		for _, field := range p.FieldMaps {
			sLine += field.toStr(v) + ","
		}
		res[k+1] = sLine
	}

	return res
}

func (p *ExportQuery) Export(datas interface{}, fileName string) error {
	ss := p.ToStrings(datas)
	if len(ss) == 0 {
		return errors.New("数据无内容")
	}

	s := strings.Join(ss, "\r\n")

	return ioutil.WriteFile(fileName, []byte(s), 0666)
}
